#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include "keycode.h"

static struct operate_handle keycode_handle;

static char * sub_string(unsigned char * des, unsigned char * src, unsigned int len)
{
	char *tmp = des;

	while(len > 0 && len--) {
		*des++ = *src++;
	}

	return tmp;
}

int ret_monitor(unsigned char * buf, unsigned char * keycode, unsigned int len)
{
	if (len == 3)
		return atoi(sub_string(buf, keycode, 1));
	else if (len == 4)
		return atoi(sub_string(buf, keycode, 2));
	else if (len == 5) 
		return atoi(sub_string(buf, keycode, 3));	
}

int ret_value(unsigned char * buf, unsigned char * keycode, unsigned int len)
{
	if (len == 8)
		return atoi(sub_string(buf, keycode+5, 1));
	else if (len == 9)
		return atoi(sub_string(buf, keycode+5, 2));
	else if (len == 10) 
		return atoi(sub_string(buf, keycode+5, 3));
	else if (len == 11) 
		return atoi(sub_string(buf, keycode+5, 4));
}

/*
 * 处理收到的键盘数据
 */
int ProcessKey(unsigned  char * keycode)
{
	int salvo_val;
	char buf[256];
	int len;
	int run_num = 0, hold_num = 0;
	
	if ( keycode == NULL) {
		perror("key code was null!\n");
		return -1;
	}
	
	memset(buf, 0, sizeof buf);	
	keycode_trace(LEVEL_5, "\t[[ %s ]]", keycode);
	len = strlen(keycode);
	keycode_trace(LEVEL_5, "length is [%d]", len);

	switch(keycode[len - 2]) {		
		case 'M':	/* 选择监视器 */
			keycode_handle.monitor_num = ret_monitor(buf, keycode, len);
			//printf("monitor num = %d\n", keycode_handle.monitor_num);
			break;
		
		case '#':	/* 选择摄像机 */
			keycode_handle.camera_num = ret_value(buf, keycode, len);
			//printf("camrema num = %d\n", keycode_handle.camera_num);
			break;		
		
		case '^':	/* 预置设置 */
			keycode_handle.shot_value = ret_value(buf, keycode, len);
			//printf("shot_set_value num = %d\n", keycode_handle.shot_value);
			keycode_handle.action = PTZ_SET_POINT;
			break;
		
		case '\\':	/* 预置调用 */
			keycode_handle.shot_value = ret_value(buf, keycode, len);
			//printf("shot_call_value num = %d\n", keycode_handle.shot_value);
			keycode_handle.action = PTZ_GOTO_POINT;
			break;
		
		case 'K':	/* 锁定 */
			break;
		
		case 'J':	/* 解锁 */
			break;
		
		case 'S':	/* 按组号轮巡 */
			run_num = keycode_handle.run_val = ret_value(buf, keycode, len);
			printf("run_val num = %d\n", keycode_handle.run_val);
			break;
		
		case '$':	/* 成组切换 */
			salvo_val = ret_value(buf, keycode, len);
			//printf("salvo_val num = %d\n", salvo_val);
			break;
		
		case 'H':	/* 暂停正在运行的巡视 */
			hold_num = keycode_handle.hold_val = ret_value(buf, keycode, len);
			printf("hold_val num = %d\n", keycode_handle.hold_val);
			break;

		case 'U':	/* 向上 */
			if (strlen(keycode) == 7)
				keycode_handle.speed = 6;
			else
				keycode_handle.speed = atoi(sub_string(buf,keycode+5,1));

			printf("speed num = %d\n", keycode_handle.speed);

			if (keycode_handle.speed > 0)
				keycode_handle.action = PTZ_UP_START;
			else if (keycode_handle.speed == 0)
				keycode_handle.action = PTZ_UP_STOP;
			break;	
		case 'D':	/* 向下 */
			if (strlen(keycode) == 7)
				keycode_handle.speed = 6;
			else
				keycode_handle.speed = atoi(sub_string(buf,keycode+5,1));

			printf("speed num = %d\n", keycode_handle.speed);

			if (keycode_handle.speed > 0)
				keycode_handle.action = PTZ_DOWN_START;
			else
				keycode_handle.action = PTZ_DOWN_STOP;
			break;
		case 'L':	/* 向左 */
			if (strlen(keycode) == 7)
				keycode_handle.speed = 6;
			else
				keycode_handle.speed = atoi(sub_string(buf,keycode+5,1));

			printf("speed num = %d\n", keycode_handle.speed);

			if (keycode_handle.speed > 0)
				keycode_handle.action = PTZ_LEFT_START;
			else
				keycode_handle.action = PTZ_LEFT_STOP;			
			break;
		case 'R':	/* 向右 */
			if (strlen(keycode) == 7)
				keycode_handle.speed = 6;
			else				
				keycode_handle.speed = atoi(sub_string(buf,keycode+5,1));

			printf("speed num = %d\n", keycode_handle.speed);

			if (keycode_handle.speed > 0)
				keycode_handle.action = PTZ_RIGHT_START;
			else
				keycode_handle.action = PTZ_RIGHT_STOP;
			break;

		case 'O':	/* 光圈开 */
			keycode_handle.action = PTZ_IRIS_OPEN_START;
			break;
		case 'C':	/* 光圈关 */
			keycode_handle.action = PTZ_IRIS_CLOSE_START;
			break;

		case 'N':	/* 焦点近 */
			keycode_handle.action = PTZ_FOCUS_NEAR_START;
			break;
		case 'F':	/* 焦点远 */
			keycode_handle.action = PTZ_FOCUS_FAR_START;
			break;

		case 'W':	/* 焦距长 */
			keycode_handle.action = PTZ_ZOOM_WIDE_START;
			break;
		case 'T':	/* 焦距短 */
			keycode_handle.action = PTZ_ZOOM_TELE_START;
			break;

		default:
			break;
	}

	//switch_camera();
	//cloud_platform_control();
	//start_list_view(keycode_handle.run_val);

	/*if (run_num > 0){
		manage_thread(run_num);
	}

	if (hold_num > 0){
		cancel_thread(hold_num);
	}*/


	return 0;
}

/*
 * 切换
 */
int switch_camera()
{
	TDeviceInfo	*pmonitor, *pcamera;	

	// 寻找监视器与摄像头.
	if ((keycode_handle.monitor_num > 0 && keycode_handle.camera_num > 0)) {
		pmonitor = search(keycode_handle.monitor_num, MONITOR);
		pcamera = search(keycode_handle.camera_num, CAMERA);
		//print_device_info(pcamera);
		//print_device_info(pmonitor);
		
		// 切换
		if (pmonitor && pcamera) 
			SwitchCamera(pmonitor, pcamera);
		else
			return -1;
	}

	return 0;
}

/*
 * 云台控制,预置设置,预置调用
 */
int cloud_platform_control()
{
	TReqPtzAct ptzact;
	TDeviceInfo	*pcamera;

	keycode_trace(LEVEL_2, "\t[[ camera_num	= %d ]]\n", keycode_handle.camera_num);
	keycode_trace(LEVEL_2, "\t[[ speed		= %d ]]\n", keycode_handle.speed);

	if (keycode_handle.camera_num > 0) {
		pcamera = search(keycode_handle.camera_num, CAMERA);
		printf("\t[%s:%d\tcamera]\n", __FUNCTION__,__LINE__);
		print_device_info(pcamera);		

		if (pcamera) {
			ptzact.ActParam.Param1 = keycode_handle.speed;

			if  ((keycode_handle.action == PTZ_SET_POINT || 
				keycode_handle.action == PTZ_GOTO_POINT) && 
				keycode_handle.shot_value > 0)
					ptzact.ActParam.Param1 = keycode_handle.shot_value;
			
			PtzControl(pcamera->IP, pcamera->Port, pcamera->ChanNum, keycode_handle.action, ptzact.ActParam);
			
		}
		else// 没找到相应camera.
			return -1;
	}
	else	// 没有摄像机编号
		return -2;

	return 0;
}

/*
 * 轮巡
 */
int start_list_view(int val)
{
	grouplist *head, *newnode, *posnode;
	struct list_head *pos;
	TDeviceInfo	*pmonitor, *pcamera;
	TReqPtzAct ptzact;
	enPtzAction action;

	printf("==== val======= = %d\n", keycode_handle.run_val );

	if ( keycode_handle.run_val > 0 ) {
		NEW_LIST_NODE(grouplist, head);
		INIT_LIST_HEAD(&head->list);

		if ( get_signle_group(head, newnode, keycode_handle.run_val) > 0 ) {						
			list_for_each(pos, &(head->list)) {
				posnode = list_entry(pos, grouplist, list);
				print_result(posnode);
				
				// 寻找监视器.
				if ( keycode_handle.monitor_num > 0 ) {
					pmonitor = search(keycode_handle.monitor_num, MONITOR);				
					print_device_info(pmonitor);
					// 没有相应编号监视器.
					if (pmonitor == NULL) {
						FREE_LIST(grouplist, head, list);
						return -1;
					}
				} // 监视器号没有输入
				else {
					FREE_LIST(grouplist, head, list);
					return -2;
				}
				
				pcamera = search(posnode->group.CameraNo, CAMERA);
				print_device_info(pcamera);
				if (pcamera) {
					// 切换
					SwitchCamera(pmonitor, pcamera);
					// 预置调用
					if (posnode->group.PresetNo > 0) {
						action = PTZ_GOTO_POINT;
						ptzact.ActParam.Param1 = posnode->group.PresetNo;						
					}
					PtzControl(pcamera->IP, pcamera->Port, pcamera->ChanNum, action, ptzact.ActParam);
					sleep(posnode->group.StopTime);
				}

				// 是否停止轮巡				
				if (!hold_view()) {
					// 轮巡停止变量清0.
					keycode_handle.hold_val = -1;	
					FREE_LIST(grouplist, head, list);

					return 1;
				}
			}

			// 释放存取数据的双链表
			FREE_LIST(grouplist, head, list);
		}
		// 没有轮巡操作编号
		else {	
			// 释放存取数据的双链表
			FREE_LIST(grouplist, head, list);

			return -4;
		}
	}
	else	// 没有轮巡操作
		return -5;

	return 0;
}

/*
 * 单组循环轮巡
 */
int single_repeat_view(int val)
{
	// 没有收到停止指令
	while ( keycode_handle.run_val != keycode_handle.hold_val )
		if ( start_list_view(val) == 0)
			continue;	
		else 
			break;
		
	//start_list_view(0);
}

/*
 * 停止轮巡
 */
int hold_view()
{
	// 相对应的轮巡组号
	if ( keycode_handle.run_val == keycode_handle.hold_val ) 
		return 0;
	else
		return -1;
}

typedef int (*function) (unsigned  char * keycode);

int run_callback(int mon, int carm, function code)
{
	code = ProcessKey;
}

/*
 * 监视器轮巡
 *	run_num : 轮巡编编号
 *	monitor : 监视器编号
 */
static int start_list_view_group(int run_num, int monitor)
{
	grouplist *head, *newnode, *posnode;
	struct list_head *pos;
	TDeviceInfo	*pmonitor, *pcamera;
	TReqPtzAct ptzact;
	enPtzAction action;

	NEW_LIST_NODE(grouplist, head);
	INIT_LIST_HEAD(&head->list);

	// 轮巡编号
	if ( get_signle_group(head, newnode, run_num) > 0 ) {	
		list_for_each(pos, &(head->list)) {
			posnode = list_entry(pos, grouplist, list);
			printf("\t[%s:%d\tgrouplist]\n", __FUNCTION__,__LINE__);
			//print_result(posnode);
		
			// 寻找监视器.
			pmonitor = search(monitor, MONITOR);				
			printf("\t[%s:%d\tmonitor]\n", __FUNCTION__,__LINE__);
			//print_device_info(pmonitor);

			// 没有监视器.
			if (pmonitor == NULL) {
				FREE_LIST(grouplist, head, list);
				return -1;
			}

			pcamera = search(posnode->group.CameraNo, CAMERA);
			printf("\t[%s:%d\tcamera]\n", __FUNCTION__,__LINE__);
			//print_device_info(pcamera);
			if (pcamera) {
				// 切换
				SwitchCamera(pmonitor, pcamera);
				// 预置调用
				if (posnode->group.PresetNo > 0) {
					action = PTZ_GOTO_POINT;
					ptzact.ActParam.Param1 = posnode->group.PresetNo;
				}
				PtzControl(pcamera->IP, pcamera->Port, pcamera->ChanNum, action, ptzact.ActParam);
				sleep(posnode->group.StopTime);
			}		
		}
	}

	// 释放存取数据的双链表
	FREE_LIST(grouplist, head, list);

	return 0;
}

pthread_t p_keycode[5];

#define PTHREAD_NAME(num)	keycode_##num##_pthread

/*
 * 线程调用函数
 */
void * keycode_0_pthread(void * arg)
{
	printf("---------------- thread one : %d --------------\n", pthread_self());
	while(0) {
		start_list_view_group(RUN_NUM_ONE, MONITOR_ONE);
		sleep(10);
	}
	start_list_view_group(RUN_NUM_ONE, MONITOR_ONE);
}

void * keycode_1_pthread(void * arg)
{
	start_list_view_group(RUN_NUM_TWO, MONITOR_TWO);
}

void * keycode_2_pthread(void * arg)
{
	start_list_view_group(RUN_NUM_THR, MONITOR_THR);
}

void * keycode_3_pthread(void * arg)
{
	start_list_view_group(RUN_NUM_FOR, MONITOR_FOR);
}

void * keycode_4_pthread(void * arg)
{
	start_list_view_group(RUN_NUM_FIV, MONITOR_FIV);	
}

/*
 * 创建五个线程.
 */
void run_thread_one()
{
	int err;
	void *ptr;

	printf("\t[%s:%d\t thread] ---------------------------\n", __FUNCTION__,__LINE__);

	err = pthread_create(&p_keycode[0], NULL, PTHREAD_NAME(0), NULL);
	if (err == 0)
        printf("thread one created.\n");
	pthread_join(p_keycode[0], &ptr);
}

void run_thread_two()
{
	int err;
	void *ptr;

	err = pthread_create(&p_keycode[1], NULL, PTHREAD_NAME(1), NULL);
	if (err == 0)
        printf("thread two created.\n");
	pthread_join(p_keycode[1], &ptr);
}

void run_thread_thr()
{
	int err;
	void *ptr;

	err = pthread_create(&p_keycode[2], NULL, PTHREAD_NAME(2), NULL);
	if (err == 0)
        printf("thread three created.\n");
	pthread_join(p_keycode[2], &ptr);
}

void run_thread_four()
{
	int err;
	void *ptr;

	err = pthread_create(&p_keycode[3], NULL, PTHREAD_NAME(3), NULL);
	if (err == 0)
        printf("thread four created.\n");
	pthread_join(p_keycode[3], &ptr);
}

void run_thread_five()
{
	int err;
	void *ptr;

	err = pthread_create(&p_keycode[0], NULL, PTHREAD_NAME(4), NULL);
	if (err == 0)
        printf("thread five created.\n");	
	pthread_join(p_keycode[4], &ptr);
}
 
static void manage_thread(int run_num)
{
	printf("\t[%s:%d\t[run = %d]]--------------------------\n", __FUNCTION__,__LINE__, run_num);
	if (run_num == 1)
		run_thread_one();
	else if (run_num == 2)
		run_thread_two();
	else if (run_num == 3)
		run_thread_thr();
	else if (run_num == 4)
		run_thread_four();
	else if (run_num == 5)
		run_thread_five();
}

static void cancel_thread(int hold_num)
{
	printf("\t[%s:%d\t[hold = %d]]===========================\n", __FUNCTION__,__LINE__, hold_num);
	if (hold_num == 1)
		pthread_cancel(p_keycode[0]);
	else if (hold_num == 2)
		pthread_cancel(p_keycode[1]);
	else if (hold_num == 3)
		pthread_cancel(p_keycode[2]);
	else if (hold_num == 4)
		pthread_cancel(p_keycode[3]);
	else if (hold_num == 5)
		pthread_cancel(p_keycode[4]);
}


static int group_switch(struct operate_handle * keycode_handle)
{
	TDeviceInfo	monitor[MONITOR_COUNT];
	TDeviceInfo	camera[CAMERA_COUNT];
	TDeviceInfo *pmonitor, *pcamera;
	unsigned int monitor_all_count = 0;	/* 监视器总数 */
	unsigned int i, monitor_position;	/* 目标监视器排列位置 */
	grouplist **group_ret;	/* 轮巡组数据 */
	int camera_count;		/* 要换切的摄像机数 */
	operate_handle handle;

	if (keycode_handle->monitor_num < 0) {
		return -1;
	}

	// 存取所有监视器
	memset(monitor, 0, sizeof monitor);
	monitor_all_count = fill_struct_deviceinfo(MON_FILE, monitor);
	
	// 确定摄像头数
	camera_count = 0;
	group_ret = group_item(keycode_handle->run_val, &camera_count);

	// 查找摄像头
	memset(camera, 0, sizeof camera);	
	for (pcamera = camera, i = 0; i < camera_count; i++, pcamera++) {
		pcamera = search(group_ret[i]->group.CameraNo, CAMERA);
	}

	// 确定目标监视器
	monitor_position = 0;
	pmonitor = monitor;
	for (monitor_position = 0; monitor_position < monitor_all_count; monitor_position++, pmonitor++) {
		if (pmonitor->DeviceNo == keycode_handle->monitor_num) {
			for (i = 0; i < camera_count; i++) {

				if (monitor[monitor_position + i].DeviceNo && camera[i].DeviceNo) {

					handle.monitor_num = monitor[i].DeviceNo;
					handle.action  = KB_EXIT_GROUP;
					RunGroup(&handle) ;

					SwitchCamera(&monitor[monitor_position+i], &camera[i]);
				}
					
					if ( monitor_position + i > monitor_all_count) {
						free(group_ret);
						return 0;
					}
			}
			if (i == camera_count) {
				free(group_ret);
				return ;
			}
		}
	}
	free(group_ret);


	return 0;
}


	// 确定摄像头数
	

	// 查找摄像头
	memset(camera, 0, sizeof camera);	
	for (pcamera = camera, i = 0; i < camera_count; i++, pcamera++) {
		pcamera = search(group_ret[i]->group.CameraNo, CAMERA);
	}

	// 切换
	// 摄像机比监视器少
	if (camera_count < monitor_all_count - monitor_position) {
		for (i = 0; i < camera_count; monitor_position++, i++) {
			SwitchCamera(&monitor[monitor_position], &camera[i]);
		}
	}
	// 摄像机等于监视器
	else if (camera_count == monitor_all_count - monitor_position) {
		for (i = 0; monitor_position < monitor_all_count; monitor_position++, i++) {
			SwitchCamera(&monitor[monitor_position], &camera[i]);
		}
	}
	// 摄像机比监视器多
	else if (camera_count > monitor_all_count - monitor_position) {
		for (i = 0; monitor_position < monitor_all_count; monitor_position++, i++) {
			SwitchCamera(&monitor[monitor_position], &camera[i]);
		}
	}
	

